Friday, May 6, 2011

Dragged div change places with destination

Hi.

Maybe a bit complex to explain. I have a grid with 9 images 100 x 100 px like this (each number symbolize a picture):

1 2 3
4 5 6
7 8 9

What I want is that the user can drag and drop e.g. 9 over 1 and they change places like this:

9 2 3
4 5 6
7 8 1

Sortables from jquery UI will not work since their solution is using floats. That will "push" all the boxes to the right or left e.g.:

9 1 2
3 4 5
6 7 8

thanks in advance.

From stackoverflow
  • take a look at this plugin:

    http://github.com/brandonaaron/jquery-swap/tree/master

  • This uses both Draggable and Droppable. The Draggable reverts to it's original position on drop. When dragging starts, the Draggable creates a function to specify where to insert the Droppable that the item gets dropped on. When the item is dropped the drop function inserts the dragged item after the item it was dropped on and invokes the insert function on the dropped item to move the Droppable to the correct position.

    $(function() {
      $('.item').draggable( {
         containment: 'parent',
         revert: true,
         revertDuration: 0,
         start: function() {
             var that = $(this);
             var previous = that.prev( '.item:last' );
             var next = that.next( '.item:first' );
             that.data( 'insert' , function(elem) {
                 if (previous.size() > 0) {
                    $(elem).insertAfter(previous);
                 }
                 else if (next.size() > 0) {
                    $(elem).insertBefore(next);
                 }
             });
         }
      });
      $('.item').droppable( {
        accept: '.item',
        drop: function(event, ui) {
           var elem = $(this);
           if (elem.siblings('.item').size() > 1) {
         ui.draggable.insertAfter(elem);
         var insert = ui.draggable.data('insert');
         insert(elem);
           }
           else { // case where there are only two elements, swap
               var parent = elem.closest('.container');
               var first = parent.children( '.item:first' );
               var last = parent.children( '.item:last' );
               last.insertBefore( first );
           }
        }
      });
    });
    
    <div id="container">
        <span class="item">1</span>
        <span class="item">2</span>
        <span class="item">3</span>
        <span class="item">4</span>
        <span class="item">5</span>
    </div>
    
  • Thanks for the fast replies!

    Your solutions looks good but the first one throws some errors when changing position 1 and 2. The second one is not quite there. But they help alot!

    I have tried to make some code that I think is a step in the right direction. What do you think?

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
    <head>
        <meta http-equiv="Content-type" content="text/html; charset=iso-8859-1" />
        <title>Drag drop 1</title>
        <script type="text/javascript" src="js/jquery-1.3.2.min.js"></script>
        <script type="text/javascript" src="js/jquery-ui-1.7.1.custom.min.js"></script>
        <script type="text/javascript">
        $(document).ready(function() {
         $(".item").draggable({
          // Elements cannot go outside #container
          containment: 'parent',
          // Make sure the element can only be dropped in a grid
          grid: [150,150],
          start: function(event, ui) {
           // Make sure picture always are on top when dragged (z-index)
           $(this).css({'z-index' : '100'});
           // Show start dragged position
           var Startpos = $(this).position();
           $("div#start").text("START: \nLeft: "+ Startpos.left + "\nTop: " + Startpos.top);
          },
          stop: function(event, ui) {
           // Revert to default layer position when dropped (z-index)
           $(this).css({'z-index' : '10'});
           // Show dropped position
           var Stoppos = $(this).position();
           $("div#stop").text("STOP: \nLeft: "+ Stoppos.left + "\nTop: " + Stoppos.top);
          }
         });
        });
        </script>
        <style>
        #container {
         width:480px;
         border:1px solid #000;
        }
        .item {
         position:relative;
         width:150px;
         height:150px;
         z-index:10;
        }
        </style>
    </head>
    <body>
        <div id="container">
         <img id="productid_1" src="images/pic1.jpg" class="item" alt="" title="" /><img id="productid_2" src="images/pic2.jpg" class="item" alt="" title="" /><img id="productid_3" src="images/pic3.jpg" class="item" alt="" title="" /><img id="productid_4" src="images/pic4.jpg" class="item" alt="" title="" /><img id="productid_5" src="images/pic5.jpg" class="item" alt="" title="" /><img id="productid_6" src="images/pic6.jpg" class="item" alt="" title="" /><img id="productid_7" src="images/pic7.jpg" class="item" alt="" title="" /><img id="productid_8" src="images/pic8.jpg" class="item" alt="" title="" /><img id="productid_9" src="images/pic9.jpg" class="item" alt="" title="" />
        </div>
        <div style="clear:both;"></div>
        <div id="start">Waiting...</div>
        <div id="stop">Waiting...</div>
    </body>
    </html>
    

Using a .net compiled dll inside native c++

Hi, as i understand that any .NET program gets compiled to MSIL which is fed to the CLR which compiles it to the assembly code and along with the help of JIT it executes it.

I was wondering, as .NET is a wrapper around the win32 api and the CLR ultimately converts the MSIL to assembly program. Isn't it possible for me to write some functionality in C#, make to a dll and then i use a tool which makes it a complete .net independent file for me to use inside unmanaged code like in C or C++.

Am i talking about Interops and COM? Isn't this idea different from it? My aim is to run a .NET dll on machine not having .NET framework.

From stackoverflow
  • It's not a supported way and many features (like Reflection) rely on metadata provided at a higher level than raw machine code. There are some programs (called .NET linkers) that might help, but they are not 100% reliable.

  • You can use the Native Image Generator (Ngen.exe) to compile a MSIL DLL to a native code DLL, but this will not allow you to run it on a system without the .NET Framework. You will still have references to other DLLs of the framework and even if you include these DLLs, it will not work on a system without the .NET framework, because the framework is more than just a collection of DLLs.

    Mehrdad Afshari : Indeed, ngen cannot remove the need to the actual assembly. An assembly is more than IL code. It contains metadata which is still needed to run.
  • If you poke around on the web, I think there are a number of tools to 'compile' .NET assemblies/code to remove their need of the framework. Not sure how well they work....

  • This KB article explains a way to call managed methods from native code. However, you still need to have the .NET framework.

Why does my Jnlp program not working with log4j ?

Hello there. I have the following problem: I've deployed in Tomcat a JNLP and an executable JAR files. JNLP file should automatically download the JAR file and execute it. The JAR file is signed and verified. This is done (the downloading part). But when to execute the JAR main class (specified in the JNLP file), a problem occurs: A part of the main class code is executed. Afterwards, when it tries to load a class that has a static final org.apache.log4j.Logger instance declared, it says an error.

Below are the representative parts of the JNLP file, the code and the error.

JNLP

<?xml version='1.0' encoding='UTF-8'?>
<jnlp spec="1.5+" codebase="http://localhost:8080/examples" href="DemoInstaller.jnlp" download="eager" main="true">
    <information>
        <title>Demo Installer</title>
        <vendor>Codemart [www.codemart.ro]</vendor>
        <homepage>https://sourceforge.net/projects/cminstall/</homepage>
        <description>This is a demo installer built using Codemart Installer framework with JavaFX</description>
        <description kind="tooltip">Codemart Demo Installer</description>
        <offline-allowed />
        <shortcut online="true">
            <desktop />
        </shortcut>
    </information>

<security>
    <all-permissions />
</security>

<update check="background" />

<resources>
    <j2se href="http://java.sun.com/products/autodl/j2se" version="1.6+" />
   <jar href="DemoInstaller.jar" main="true" download="eager" />
</resources>

<application-desc main-class="ro.codemart.installer.packer.ant.impl.nestedjar.Main" />

The main class:

public class Main {
 public static void main(String[] args) throws Exception {
     final Main main = new Main();
     //this is the problem class !
     Class clazz = Class.forName("WizardRunner");
     Method m = clazz.getMethod("main", new Class[]{args.getClass()});
     m.invoke(null, new Object[]{args});      
    ...
   }
}

And the problem class:

public class WizardRunner{

    private final static Logger log = Logger.getLogger(WizardRunner.class);
...
}

And the error:

log4j:ERROR Could not find [log4j.dtd]. Used [sun.misc.Launcher$AppClassLoader@d9f9c3] class loader in the search. log4j:ERROR Could not parse url [jar:http://localhost:8080/examples/DemoJar.jar!/log4j.xml]. java.io.FileNotFoundException: JAR entry log4j.dtd not found in at com.sun.jnlp.JNLPCachedJarURLConnection.connect(Unknown Source) at com.sun.jnlp.JNLPCachedJarURLConnection.getInputStream(Unknown Source) at com.sun.org.apache.xerces.internal.impl.XMLEntityManager.setupCurrentEntity(Unknown Source) at com.sun.org.apache.xerces.internal.impl.XMLEntityManager.startEntity(Unknown Source) at com.sun.org.apache.xerces.internal.impl.XMLEntityManager.startDTDEntity(Unknown Source) at com.sun.org.apache.xerces.internal.impl.XMLDTDScannerImpl.setInputSource(Unknown Source) at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$DTDDriver.dispatch(Unknown Source) at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$DTDDriver.next(Unknown Source) at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$PrologDriver.next(Unknown Source) at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(Unknown Source) at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown Source) at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source) at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source) at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(Unknown Source) at com.sun.org.apache.xerces.internal.parsers.DOMParser.parse(Unknown Source) at com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderImpl.parse(Unknown Source) at javax.xml.parsers.DocumentBuilder.parse(Unknown Source) at org.apache.log4j.xml.DOMConfigurator$2.parse(DOMConfigurator.java:612) at org.apache.log4j.xml.DOMConfigurator.doConfigure(DOMConfigurator.java:711) at org.apache.log4j.xml.DOMConfigurator.doConfigure(DOMConfigurator.java:618) at org.apache.log4j.helpers.OptionConverter.selectAndConfigure(OptionConverter.java:470) at org.apache.log4j.LogManager.(LogManager.java:122) at org.apache.log4j.Logger.getLogger(Logger.java:117) at ro.codemart.installer.wizard.WizardRunner.(WizardRunner.java:38) at java.lang.Class.forName0(Native Method) at java.lang.Class.forName(Unknown Source) at ro.codemart.installer.packer.ant.impl.nestedjar.Main.executeApplicationMainClass(Main.java:216) at ro.codemart.installer.packer.ant.impl.nestedjar.Main.main(Main.java:290) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) at java.lang.reflect.Method.invoke(Unknown Source) at com.sun.javaws.Launcher.executeApplication(Unknown Source) at com.sun.javaws.Launcher.executeMainClass(Unknown Source) at com.sun.javaws.Launcher.doLaunchApp(Unknown Source) at com.sun.javaws.Launcher.run(Unknown Source) at java.lang.Thread.run(Unknown Source) log4j:WARN No appenders could be found for logger (WizardRunner). log4j:WARN Please initialize the log4j system properly.

Thank you!

From stackoverflow
  • If you look in your stack trace the cause of the error is a FileNotFoundException for log4j.dtd. Look at how the DTD is referenced from your log4j.xml. Is the DTD included in your jar file? It needs to be in a place where the JVM can load it.

  • Yes, the log4j.dtd file comes embedded with log4j-1.2.12.jar. Also this log4j jar is in the classpath.

    Mark : So you need to investigate why it cannot be loaded. Is the log4j jar within DemoInstaller.jar as it is not listed in the JNLP file.
  • I think the problem is missing log4j.jar - it's not specified or loaded by the .jnlp file. You mentioned in the previous answer that it's in your classpath, but how if you're running via WebStart? I believe your classpath is limited to what's defined in the .jnlp file.

    Try adding

    <jar href="log4j.jar" main="true" download="eager" />
    

    to

    <resources>
    

Monitor.Wait/Pulse race condition in a multithreaded server

I'm having a problem with interlocked Monitor.Wait and Monitor.Pulse in a multi-threaded TCP server. To demonstrate my issues, here is my server code:

public class Server
{
    TcpListener listener;
    Object sync;
    IHandler handler;
    bool running;

    public Server(IHandler handler, int port)
    {
        this.handler = handler;
        IPAddress address = Dns.GetHostEntry(Dns.GetHostName()).AddressList[0];
        listener = new TcpListener(address, port);
        sync = new Object();
        running = false;
    }

    public void Start()
    {
        Thread thread = new Thread(ThreadStart);
        thread.Start();
    }

    public void Stop()
    {
        lock (sync)
        {
            listener.Stop();
            running = false;
            Monitor.Pulse(sync);
        }
    }

    void ThreadStart()
    {
        if (!running)
        {
            listener.Start();
            running = true;
            lock (sync)
            {
                while (running)
                {
                    try
                    {
                        listener.BeginAcceptTcpClient(new AsyncCallback(Accept), listener);
                        Monitor.Wait(sync);  // Release lock and wait for a pulse
                    }
                    catch (Exception e)
                    {
                        Console.WriteLine(e.Message);
                    }
                }
            }
        }
    }

    void Accept(IAsyncResult result)
    {
        // Let the server continue listening
        lock (sync)
        {
            Monitor.Pulse(sync);
        } 

        if (running)
        {
            TcpListener listener = (TcpListener)result.AsyncState;
            using (TcpClient client = listener.EndAcceptTcpClient(result))
            {
                handler.Handle(client.GetStream());
            }
        }
    }
}

And here is my client code:

class Client
{
    class EchoHandler : IHandler
    {
        public void Handle(Stream stream)
        {
            System.Console.Out.Write("Echo Handler: ");
            StringBuilder sb = new StringBuilder();
            byte[] buffer = new byte[1024];
            int count = 0;
            while ((count = stream.Read(buffer, 0, 1024)) > 0)
            {
                sb.Append(Encoding.ASCII.GetString(buffer, 0, count));
            }
            System.Console.Out.WriteLine(sb.ToString());
            System.Console.Out.Flush();
        }
    }

    static IPAddress localhost = Dns.GetHostEntry(Dns.GetHostName()).AddressList[0];

    public static int Main()
    {
        Server server1 = new Server(new EchoHandler(), 1000);
        Server server2 = new Server(new EchoHandler(), 1001);

        server1.Start();
        server2.Start();

        Console.WriteLine("Press return to test...");
        Console.ReadLine();

        // Note interleaved ports
        SendMsg("Test1", 1000);
        SendMsg("Test2", 1001);
        SendMsg("Test3", 1000);
        SendMsg("Test4", 1001);
        SendMsg("Test5", 1000);
        SendMsg("Test6", 1001);
        SendMsg("Test7", 1000);

        Console.WriteLine("Press return to terminate...");
        Console.ReadLine();

        server1.Stop();
        server2.Stop();

        return 0;
    }

    public static void SendMsg(String msg, int port)
    {
        IPEndPoint endPoint = new IPEndPoint(localhost, port);

        byte[] buffer = Encoding.ASCII.GetBytes(msg);
        using (Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
        {
            s.Connect(endPoint);
            s.Send(buffer);
        }
    }
}

The client sends seven messages, but the server only prints four:

Press return to test...

Press return to terminate...
Echo Handler: Test1
Echo Handler: Test3
Echo Handler: Test2
Echo Handler: Test4

I suspect the monitor is getting confused by allowing the Pulse to occur (in the server's Accept method) before the Wait occurs (in the ThreadStart method), even though the ThreadStart should still have the lock on the sync object until it calls Monitor.Wait(), and then the Accept method can acquire the lock and send its Pulse. If you comment out these two lines in the server's Stop() method:

//listener.Stop();
//running = false;

The remaining messages appear when the server's Stop() method is called (i.e. waking up the server's sync object causes it to dispatch the remaining incoming messages). It seems to me this can only occur in a race condition between the ThreadStart and Accept methods, but the lock around the sync object should prevent this.

Any ideas?

Many thanks, Simon.

ps. Note that I'm aware that the output appears out-of-order etc., I'm specifically asking about a race condition between locks and the Monitor. Cheers, SH.

From stackoverflow
  • The problem is that you are using Pulse/Wait as a signal. A proper signal, such as a AutoResetEvent has a state such that it stays signalled until a thread has called WaitOne(). Calling Pulse without any threads waiting on it will become a noop.

    This is combined with the fact that a lock can be taken many times by the same thread. Since you are using Async programming the Accept callback can be called by the same thread that did the BeginAcceptTcpClient.

    Let me illustrate. I commented out the second server, and changed some code on your server.

    void ThreadStart()
    {
        if (!running)
        {
            listener.Start();
            running = true;
            lock (sync)
            {
                while (running)
                {
                    try
                    {
                        Console.WriteLine("BeginAccept [{0}]", 
                            Thread.CurrentThread.ManagedThreadId);
                        listener.BeginAcceptTcpClient(new AsyncCallback(Accept), listener);
                        Console.WriteLine("Wait [{0}]", 
                            Thread.CurrentThread.ManagedThreadId);
                        Monitor.Wait(sync);  // Release lock and wait for a pulse
                    }
                    catch (Exception e)
                    {
                        Console.WriteLine(e.Message);
                    }
                }
            }
        }
    }
    
    void Accept(IAsyncResult result)
    {
        // Let the server continue listening
        lock (sync)
        {
            Console.WriteLine("Pulse [{0}]", 
                Thread.CurrentThread.ManagedThreadId);
            Monitor.Pulse(sync);
        }
        if (running)
        {
            TcpListener localListener = (TcpListener)result.AsyncState;
            using (TcpClient client = localListener.EndAcceptTcpClient(result))
            {
                handler.Handle(client.GetStream());
            }
        }
    }
    

    The output from my run shown below. If you run this code yourself the values will differ, but it will be the same in general.

    Press return to test...
    BeginAccept [3]
    Wait [3]
    
    Press return to terminate...
    Pulse [5]
    BeginAccept [3]
    Pulse [3]
    Echo Handler: Test1
    Echo Handler: Test3
    Wait [3]
    

    As you can see there are two Pulse's called, one from a separate thread (the Pulse [5]) which wakes up the first Wait. Thread 3 then does another BeginAccept, but having Pending incoming connections that thread decides to call the Accept callback immediately. Since the Accept is called by the same thread, the Lock(sync) doesn't block but Pulse [3] immediately on an empty thread queue.

    Two handlers are invoked and handles the two messages.

    Everything is fine, and the ThreadStart start to run again and goes to Wait indefinitely.

    Now, the underlying issue here is that you are trying to use a monitor as a signal. Since it doesn't remember the state the second Pulse get's lost.

    But there is an easy solution for this. Use AutoResetEvents, which is a proper signal and it will remember its state.

    public Server(IHandler handler, int port)
    {
        this.handler = handler;
        IPAddress address = Dns.GetHostEntry(Dns.GetHostName()).AddressList[0];
        listener = new TcpListener(address, port);
        running = false;
        _event = new AutoResetEvent(false);
    }
    
    public void Start()
    {
        Thread thread = new Thread(ThreadStart);
        thread.Start();
    }
    
    public void Stop()
    {
        listener.Stop();
        running = false;
        _event.Set();
    }
    
    void ThreadStart()
    {
        if (!running)
        {
            listener.Start();
            running = true;
            while (running)
            {
                try
                {
                    listener.BeginAcceptTcpClient(new AsyncCallback(Accept), listener);
                    _event.WaitOne();
                }
                catch (Exception e)
                {
                    Console.WriteLine(e.Message);
                }
            }
        }
    }
    
    void Accept(IAsyncResult result)
    {
        // Let the server continue listening
        _event.Set();
        if (running)
        {
            TcpListener localListener = (TcpListener) result.AsyncState;
            using (TcpClient client = localListener.EndAcceptTcpClient(result))
            {
                handler.Handle(client.GetStream());
            }
        }
    }
    

Multiply defined symbols

Hi, If I declare a global variable in a header file and include it in two .cpp files, the linker gives an error saying the symbol is multiply defined. My question is, why does this happen for only certain types of object (eg. int) and not others (eg. enum)?

The test code I used is given below:

test.h

#ifndef TEST_HEADER
#define TEST_HEADER

namespace test
{           
        int i_Test1 = -1;
        int i_Test2 = -1;
};

#endif // TEST_HEADER

class1.h

#ifndef CLASS_1_HEADER
#define CLASS_1_HEADER

class class1
{
public:
        void count();
};

#endif //CLASS_1_HEADER

class1.cpp

#include <iostream>
#include "class1.h"
#include "test.h"

void class1::count()
{
        std::cout << test::i_Test1 << std::endl;
}

class2.h

#ifndef CLASS_2_HEADER
#define CLASS_2_HEADER

class class2
{
public:
        void count();
};

#endif //CLASS_2_HEADER

class2.cpp

#include "class2.h"
#include <iostream>
#include "test.h"

void class2::count()
{
        std::cout << test::i_Test2 << std::endl;
}

main.cpp

#include "class1.h"
#include "class2.h"

int main(int argc, char** argv)
{
        class1 c1;
        class2 c2;
        c1.count();
        c2.count();
        return -1;
}

Building this code with:

g++ main.cpp class1.cpp class2.cpp -o a

produces the following output:

ld: fatal: symbol test::i_Test1' is multiply-defined: (file /var/tmp//ccwWLyrM.o type=OBJT; file /var/tmp//ccOemftz.o type=OBJT); ld: fatal: symbol test::i_Test2' is multiply-defined: (file /var/tmp//ccwWLyrM.o type=OBJT; file /var/tmp//ccOemftz.o type=OBJT); ld: fatal: File processing errors. No output written to a collect2: ld returned 1 exit status

If I change the test.h file as given below:

test.h (with enum)

#ifndef TEST_HEADER
#define TEST_HEADER

namespace test
{
        enum val
        {
                i_Test1 = 5,
                i_Test2
        };
        //int i_Test1 = -1;
        //int i_Test2 = -1;
};

#endif // TEST_HEADER

I don't get the "multiply defined" error and the program gives the desired output:

5
6
From stackoverflow
  • That's because enumerations are not objects - they are types. Class types (class,struct,union) and enumerations can be defined multiple times throughout the program, provided all definitions satisfy some restrictions (summed up by the so-called One Definition Rule (ODR)). The two most important ones are

    • All definitions have the same token sequence (textual identical)
    • Names used must have the same meaning (resolve to the same things) in all definitions. (this is a requirement on the context of the definition)

    Your enumeration definition satisfies all conditions of the ODR. Therefor, that is valid and no reason for the linker / compiler to moan (actually, for a violation of the ODR the compiler is not required to issue a message either - most of it falls under the so-called no diagnostic required rule, some violations also result in undefined behavior).

    However, for every non-inline function and object, these must be only defined one time. Multiply defining those result in spurious errors, like in your case. To solve it, put only a declaration into the header file (using "extern" without an initializer) and put one definition into one of those .cpp files (omitting the "extern" then, or putting an initializer. If it is a const object, you still need the "extern", since per default const variables have internal linkage, and the symbol would not be exported otherwise).

SharePoint Approval Workflow

I have a custom content type in SharePoint which has an approval workflow associated with it. The content type contains several Choice Site Columns. There is now a requirement to change the values of the choice columns AND update the existing content to reflect the new values.

Eg,

Existing Choices:
Choice 1
Choice 2
Choice 3

New Choices
Choice 1a
Choice 2a
Choice 3

So, some of the choices are being renamed.

As far as i can tell, whilst changing the choice column is straight forward, the existing list items won't automatically pick up the new values i.e. a list item with Choice 1 selected will still show Choice 1 until the list item is physically edited. But editing the item will require re-approval of the workflow. There are a few thousand items spread over several lists which will be affected by this change.

So, my question: Is it possible to suspend or detach the workflow whilst the changes are made and then re-attach / re-activate after the changes have been made, thus avoiding the need to re-approve everything? Or am i best to look at automating the re-approval?

Any help much appreciated

From stackoverflow
  • Hi,

    You could update the values using the object model, the SPListItem.SystemUpdate method that optionally allows you to prevent that a new version is created.

    You could use SPSiteDataQuery to find all items using your content type and then update them using the method mentioned above.

    Regards, Daniel Karlsson

    Temple : Excellent. Does exactly what I need. Thanks

Store form data in MySQL with jQuery.ajax

Edit: I found the soluton for getting the correct URL. Se the solution in this thread.

Hi, I'm having problems prosessing a form so that I can save it's data in my MySQL database. I'm using Wordpress as CMS.

I've used this example: http://www.ryancoughlin.com/2008/11/04/use-jquery-to-submit-form

I'm pretty sure that the source of my problem, is that I'm using the wrong url: in the javascript. The error message only returns 'undefined' and Firebug reports a page not found 404 error.

So what would be the correct url? Any help would be greatly appreciated.

This is my site structure:

Mywebsite (folder)      
  sl_register.tpl.php   
  includes    (folder)    
  storelocator (folder)
    process_frm_store.php
    frm_store.php
  js (folder)
    myscripts.js

And this is the logic of my site build up:

sl_register.tpl.php:

<?php
/*
  Template Name: SL - Register Store
*/  
  get_header();
  include_once 'includes/storeLocator/frm_store.php';
  get_footer();
?>

frm_store.php:

<form id="store_data_form" class="appnitro"  method="post" action="">
  <input id="store_active" name="store_active" type="hidden" value="pending" />
  <input id="store_name" name="store_name" type="text" value=""/> 
  <input id="store_street1" name="store_street1" type="text" value="" />
  <input id="saveForm" class="submitButton" type="submit" name="save" value="Save" />
</form>

process_frm_store.php:

<?php
  $myDB = new DAL(); 
  $myDB->connect();

  if (isset($_POST['save'])) 
  {
    $formData =  array(
      "name"=> mysql_real_escape_string($_POST['store_name']),
      "street1"=> mysql_real_escape_string($_POST['store_street1']),
      "zipcode"=> mysql_real_escape_string($_POST['store_zipcode']));

    $myDB->addNewStore($formData);
  }
?>

myscripts.js:

jQuery.processForms = function()
{
  jQuery('form#store_data_form').submit(function() 
  {
    var store_name = 'Test store'; //jQuery("input#store_name").val();
    var store_street1 = 'Sesamy street';//Set constant for testing
    var store_zipcode = '0574'; //Set constant for testing
    var dataString = 'name='+ store_name + '&street1=' + store_street1 + '&zipcode=' + store_zipcode;    
    jQuery.ajax(
    {   
      type: "POST",   
      url: "process_frm_store.php",   
      data: dataString,
      error: function(XMLHttpRequest, textStatus, errorThrown) 
      { 
        alert(errorThrown); // Just for debugging
        jQuery('#suggestNewStore div.error').fadeIn(); 
      },
      success: function() 
      {
        alert('It works!');
        jQuery('#suggestNewStore div.success').fadeIn();   
      }   
    });   
    return false;      
  });
}
From stackoverflow
  • It it simpler to user the absolute path like http://www.yourwebsite.com/storelocator/process_frm_store.php to be on the safe-side.

    Otherwise the url param of the .ajax method should be storelocator/process_frm_store.php because your ..js file is included and executed in your base path, outside the js or storelocator folders

    Steven : Thanks for your answer Bogdan. I don't think that will work though, since I'm using Wordpress CMS with user friendly URL's. The URL for my page / form is: http://localhost/mysite/store-locator/register-store-label The logical URL is: http://localhost/mysite/sl_register.tpl.php Firebugs reports he following error: POST (url) 404 Not Found Where url is whatever i put in my javascript file.
  • You have <?php tags wrapped around your include_once in sl_register.tpl.php when it is already inside of <?php tags ...unless you're doing something that I don't understand this is probably breaking something.

    Steven : Oh sorry... that's just a typo from my cut and paste. In my full code, that line is outside PHP tags. I'll edit and fix this.
  • I've currently given up trying to get this to work. I'll get back to this once I've solved some other issues which are related.

    Stuart Branham : Rather than posting this as an answer, it's better for these types of comments to be edits in your question or a comment on your question.
    Steven : I'm marking this as correct answer, since I can't mark my first post. And since I can only comment, and not post, a new answer to my own problem, take a look at my Edit at the top.